Skip to main content

Variables for descendant styles

It is not uncommon to define styles on an element that are dependent on a parent element's state, such as applying some styles conditionally when the parent element is hovered.

StyleX doesn't allow arbitrary selectors or "styling at a distance". However, variables can be used to achieve the same results in a safe and composable way.

Example: Sidebar

Consider the case where the content within a sidebar needs to have conditional styles applied when the sidebar as whole is hovered.

Using CSS variables, you can style descendants based on a parent's state, such as :hover.

Step 1

Define one or more variables using stylex.defineVars:

// variables.stylex.ts
import * as stylex from '@stylexjs/stylex';

export const vars = stylex.defineVars({
childColor: 'black',
});

Step 2

Define conditional styles setting the value for the variable in the ancestor component.

import * as stylex from '@stylexjs/stylex';
import { vars } from './variables.stylex';

const styles = stylex.create({
parent: {
[vars.childColor]: {
default: 'black',
':hover': 'blue',
},
},
});

function ParentWithHover({children}) {
return (
<div {...stylex.props(styles.parent)}>
{children}
</div>
);
}

Step 3

Use the variable to style the child component

import * as stylex from '@stylexjs/stylex';
import { vars } from './variables.stylex';

const styles = stylex.create({
child: {
color: vars.childColor,
}
});

function ParentWithHover() {
return (
<span {...stylex.props(styles.child)}><Icon />A Row</span>
);
}

This pattern makes it explicit what styles are being defined on an ancestor element, while leaving the child element in control to use those styles explicitly and to override it as needed.